<template>
  <div class="physical-sensors">
    <el-icon class="close-icon" :size="18" :color="'#FF7071'" @click="deleteNode">
      <CircleCloseFilled />
    </el-icon>
    <div class="ps-header">
      <div class="title">物理传感器</div>
      <div class="expand-btn" @click="isExpand = !isExpand">{{ isExpand ? '收起' : '展开' }}</div>
    </div>
    <div class="ps-body" @mousedown.stop>
      <el-form :model="sensorData" label-width="100px">
        <el-form-item label="物理传感器" prop="id">
          <el-select
            v-model="sensorData.sensorId"
            clearable
            filterable
            style="width: 100%"
            placeholder="请选择物理传感器"
            :disabled="isDisabled"
            @change="sensorChange"
          >
            <el-option
              v-for="item in sensorList"
              :key="item.sensorId"
              :label="item.sensorId + '(' + item.outputSignalType + ')'"
              :value="item.sensorId"
            />
          </el-select>
        </el-form-item>

        <el-form-item label="输出信号类型" class="special-item">
          {{ getSensorOutputSignalType(sensorData.sensorId) }}
        </el-form-item>
        <template v-if="isExpand">
          <el-form-item label="X轴位置" prop="positionX">
            <el-input
              v-model="sensorData.positionX"
              placeholder="请输入"
              @change="handleUpdateNode"
              :disabled="isDisabled"
            />
          </el-form-item>

          <el-form-item label="Y轴位置" prop="positionY">
            <el-input
              v-model="sensorData.positionY"
              placeholder="请输入"
              @change="handleUpdateNode"
              :disabled="isDisabled"
            />
          </el-form-item>
          <el-form-item label="Z轴位置" prop="positionZ">
            <el-input
              v-model="sensorData.positionZ"
              placeholder="请输入"
              @change="handleUpdateNode"
              :disabled="isDisabled"
            />
          </el-form-item>
        </template>
      </el-form>
    </div>

    <Handle id="sensor_a" type="source" :position="Position.Right" />
  </div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { CircleCloseFilled } from '@element-plus/icons-vue'
import { Handle, Position, useVueFlow, useNodeConnections, useNodesData } from '@vue-flow/core'

const props = defineProps<{
  node: any
  taskHook: any
}>()

const emits = defineEmits(['sensorDataChange'])
const { updateNode, removeNodes, toObject, removeEdges, getSelectedEdges, removeSelectedEdges } =
  useVueFlow()
const { sensorList, getSensorOutputSignalType, isMatchSignalType } = props.taskHook
const { node } = toRefs(props)

const sensorData = ref<any>({
  sensorId: '',
  sensorObj: null,
  nodeId: node.value.id,
  positionX: '',
  positionY: '',
  positionZ: ''
})

if (node.value.data.sensorData) {
  sensorData.value = node.value.data.sensorData
}

const isExpand = ref(false)

const handleUpdateNode = () => {
  const sensorObj = sensorList.value.find((item) => item.sensorId === sensorData.value.sensorId)
  sensorData.value.sensorObj = sensorObj
  updateNode(node.value.id, {
    data: {
      sensorData: sensorData.value
    }
  })
}

// 与传感器相连的sau连线
const targetConnections = useNodeConnections({
  handleType: 'source'
})

// 与传感器相连的节点数据
const sauNodesData = useNodesData(() =>
  targetConnections.value.map((connection) => connection.target)
)

// 当相连的sau存在已经创建好的实例时，禁止传感器选择改变
const isDisabled = computed(() => {
  return sauNodesData.value.some((item) => item.data.sauInstanceId)
})

const sensorChange = () => {
  // 传感器改变，去除类型不匹配的连线
  const { edges, nodes } = { ...toObject() }
  const filteredEdges = edges.filter((item) => item.source === node.value.id)
  filteredEdges.forEach((item) => {
    const targetNode = nodes.find((node) => node.id === item.target)
    if (
      !(
        targetNode &&
        isMatchSignalType(targetNode.data.sauData.sauTemplateId, sensorData.value.sensorId)
      )
    ) {
      removeEdges([item])
    }
  })

  handleUpdateNode()
  emits('sensorDataChange')
}

const deleteNode = () => {
  removeSelectedEdges(getSelectedEdges.value)
  removeNodes([node.value.id])
}
</script>
<style lang="scss" scoped>
.physical-sensors {
  width: 300px;
  height: auto;
  cursor: pointer;
  .close-icon {
    position: absolute;
    top: -15px;
    right: -15px;
    font-size: 18px;
  }

  .ps-header {
    background: url('@/assets/task/task01.png') 12px center / 25px 25px no-repeat;
    padding: 4px 10px 4px 49px;
    color: #333;
    font-size: 14px;
    display: flex;
    justify-content: space-between;

    .expand-btn {
      color: #00b1b2;
    }
  }

  .ps-body {
    padding: 10px 10px 0;
    cursor: default;
  }
}
</style>
